/*================================================================================
// File Name: sm3_compressor.v
// Author: atom
// Created Time: 2023年11月24日 星期五 23时01分59秒
//
//       *         *********       ****            *         *     
//      * *            *          *    *          * *       * *    
//     *   *           *         *      *        *   *     *   *   
//    *******          *         *      *       *     *   *     *  
//   *       *         *          *    *       *       * *       * 
//  *         *        *           ****       *         *         *
================================================================================*/
`include "sm3_param.v"

module sm3_compressor(
    input                   clk,
    input                   rst_n,

    input   [63:0] [31:0]   din,
    input   [63:0] [31:0]   din1,
    input                   din_vld,

    output  [255:0]         hash_key,
    output                  hash_key_vld
);




// 1cycle process 8 round
wire    [PIPELINE_NUM:0] [31:0] a,b,c,d,e,f,g,h;
wire    [31:0]                  a_fin,b_fin,c_fin,d_fin,e_fin,f_fin,g_fin,h_fin; 

reg     [PIPELINE_NUM-1:0]      hash_key_vld_d;

assign a[0] = A_INIT;
assign b[0] = B_INIT;
assign c[0] = C_INIT;
assign d[0] = D_INIT;
assign e[0] = E_INIT;
assign f[0] = F_INIT;
assign g[0] = G_INIT;
assign h[0] = H_INIT;

generate
genvar i;
    for(i=0;i<PIPELINE_NUM;i=i+1)
        sm3_compressor_group x_com_grp_i(
            .clk(clk),
            .rst_n(rst_n),

            .a(a[i]),
            .b(b[i]),
            .c(c[i]),
            .d(d[i]),
            .e(e[i]),
            .f(f[i]),
            .g(g[i]),
            .h(h[i]),
            
            .w(din[(GROUP_NUM*(i+1))-1-:GROUP_NUM]),
            .w1(din1[(GROUP_NUM*(i+1))-1-:GROUP_NUM]),
            .pipeline_idx(i),

            .new_a(a[i+1]),
            .new_b(b[i+1]),
            .new_c(c[i+1]),
            .new_d(d[i+1]),
            .new_e(e[i+1]),
            .new_f(f[i+1]),
            .new_g(g[i+1]),
            .new_h(h[i+1])
        );
endgenerate

assign a_fin[31:0] = A_INIT + a[PIPELINE_NUM-1];
assign b_fin[31:0] = A_INIT + b[PIPELINE_NUM-1];
assign c_fin[31:0] = A_INIT + c[PIPELINE_NUM-1];
assign d_fin[31:0] = A_INIT + d[PIPELINE_NUM-1];
assign e_fin[31:0] = A_INIT + e[PIPELINE_NUM-1];
assign f_fin[31:0] = A_INIT + f[PIPELINE_NUM-1];
assign g_fin[31:0] = A_INIT + g[PIPELINE_NUM-1];
assign h_fin[31:0] = A_INIT + h[PIPELINE_NUM-1];

assign hash_key[255:0] = {a_fin[31:0],b_fin[31:0],c_fin[31:0],d_fin[31:0]
                          e_fin[31:0],f_fin[31:0],g_fin[31:0],h_fin[31:0]};

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        hash_key_vld_d[PIPELINE_NUM-1:0] <= {PIPELINE_NUM{1'b0}};
    else
        hash_key_vld_d[PIPELINE_NUM-1:0] <= {hash_key_vld_d[PIPELINE_NUM:1],din_vld};
end 

assign hash_key_vld = hash_key_vld_d[PIPELINE_NUM];

endmodule
